package com.example.hctorisrael.deadolympics;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.scene.background.AutoParallaxBackground;
import org.andengine.entity.scene.background.ParallaxBackground;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.scene.menu.MenuScene;
import org.andengine.entity.scene.menu.item.IMenuItem;
import org.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.andengine.entity.scene.menu.item.decorator.ScaleMenuItemDecorator;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.util.GLState;

import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by HectorIsrael on 03/05/2015.
 */
public class EscenaJuegoTres extends EscenaBase {
    //SONIDOS*****
    private Music musicaFondo;
    private Sound efectoExplosion;
    private Sound efectoChoque;
    //Pausa
    private MenuScene escenaPausa;
    private Sprite fondoPausa;
    private final int OPCION_CONTINUAR = 0;
    private final int OPCION_MENU = 1;
    private Sprite spriteBtnPausa;
    private boolean estaEnPausa = false;
    //SPRITE TIMER
    private AnimatedSprite timer;
    //MENSAJES GANASTE / PERDISTE
    private Sprite mensajePerdiste;
    private Sprite mensajeGanaste;
    //FONDO
    private Sprite spriteFondoJuegoTres;
    //PERSONAJE
    private Sprite spriteShooter;
    private int caidas=0;
    //Sprite Animado de la nave
    private AnimatedSprite nave;
    //Sprite Animado de la chocando
    private AnimatedSprite naveChocando;
    //Marcador
    public Marcador marcador;
    //Tiempo para agregar cabezas
    private float tiempoTranscurrido;
    ArrayList<Bala> lista = new ArrayList<>();
    ArrayList<cabezaHombre> listaCH = new ArrayList<>();
    public int puntaje = 600;
    //Asteroides enemigos
    private Asteroide asteroide;
    private Asteroide asteroideDos;
    private Asteroide asteroideTres;
    private boolean acabo =false;
    //Contador de Chocques
    private int choques = 0;
    private int cont=0;
    private int tiempo = 600;


    @Override
    public void crearEscena() {
        agregarFondo();
        agregarBtnPausa();
        crearEscenaPausa();
        agregarNave();
        agregarAsteroide();
        agregarAsteroideDos();
        agregarAsteroideTres();
        agregarTimerAnimado();
        agregarMarcador();
        crearSonidos();
    };

    private void agregarFondo(){
        float x = admRecursos.regionFondoJuegoTres.getWidth()/2;
        float y = ControlJuego.ALTO_CAMARA/2;

        spriteFondoJuegoTres = new Sprite(x,y, admRecursos.regionFondoJuegoTres,admRecursos.vbom);
        AutoParallaxBackground fondo = new AutoParallaxBackground(0,0,0,10);
        fondo.attachParallaxEntity(new ParallaxBackground.ParallaxEntity(-25,spriteFondoJuegoTres));

        setBackground(fondo);
        setBackgroundEnabled(true);
    }

    protected void onManagedUpdate(float pSecondsElapsed){
        if(estaEnPausa){
            musicaFondo.pause();
            setIgnoreUpdate(true);  // Ya no ejecuta este metodo
            pausar(); // Mostrar la escena de pausa
            return;
        }

        if(!acabo && timer.isAnimationRunning()){
            tiempo -- ; // el tiempo disminuye (10 segundos--)
            //Se giran y mueven los asteroides
            asteroide.mover(-12, 0);
            asteroideDos.mover(-11,0);
            asteroideTres.mover(-10, 0);
            asteroide.girar(5);
            asteroideDos.girar(7);
            asteroideTres.girar(3);

            //Posicion aleatroia del asteroide 3 cuando sale
            if( asteroideTres.getSpriteAsteroide().getX() < 0){
                puntaje+=8;
                float pos3X = (float)(Math.random()*ControlJuego.ANCHO_CAMARA);
                float pos3Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroideTres.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA,pos3Y);
            }
            //Posicion aleatroia del asteroide 1 cuando sale
            if( asteroide.getSpriteAsteroide().getX() < 0 ){
                puntaje+=8;
                float pos1X = (float)(Math.random()*ControlJuego.ANCHO_CAMARA);
                float pos1Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroide.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA,pos1Y);
            }
            //Posicion aleatroia del asteroide 2 cuando sale
             if( asteroideDos.getSpriteAsteroide().getX() < 0){
                 puntaje+=8;
                float pos2X = (float)(Math.random()*ControlJuego.ANCHO_CAMARA);
                float pos2Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroideDos.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA,pos2Y);
            }

            if(nave.collidesWith(asteroide.getSpriteAsteroide())){
                choques ++ ;
                efectoChoque.play();
                float pos1Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroide.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA,pos1Y);

            }
            if(nave.collidesWith(asteroideDos.getSpriteAsteroide())){
                choques ++;
                efectoChoque.play();
                float pos2Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroideDos.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA,pos2Y);
            }

            if( nave.collidesWith(asteroideTres.getSpriteAsteroide())){
                choques ++ ;
                efectoChoque.play();
                float pos3Y = (float)(Math.random()*ControlJuego.ALTO_CAMARA);
                asteroideTres.getSpriteAsteroide().setPosition(ControlJuego.ANCHO_CAMARA, pos3Y);
            }

            if(tiempo <=0 && !acabo && timer.isAnimationRunning()){
                acabo = true;
                marcador.aumentarMarcador(puntaje);
                modificarVidas();
                siguienteEscena();
            }

            if(choques >= 3 && !acabo && cont ==0){
                acabo = true;
                nave.detachSelf();
                marcador.disminuirVidas(1);
                asteroide.getSpriteAsteroide().detachSelf();
                asteroideDos.getSpriteAsteroide().detachSelf();
                asteroideTres.getSpriteAsteroide().detachSelf();
                agregarNaveChocando();
                modificarVidas();
                efectoExplosion.play();
                timer.detachSelf();

                cont=1;
            }

            if(nave.getY()> ControlJuego.ALTO_CAMARA){
                nave.setY(ControlJuego.ALTO_CAMARA -5);
            }
            if(nave.getY()< 0){
                nave.setY(5);
            }
        }
        if(cont==1){
            if(naveChocando.isAnimationRunning()==false){
                naveChocando.detachSelf();
                naveChocando.dispose();
                siguienteEscena();
            }
        }

        super.onManagedUpdate(pSecondsElapsed);
    }

    private void agregarNave(){
        TiledTextureRegion regionNave = admRecursos.regionNave;
        nave = new AnimatedSprite(150, 240,
                regionNave, admRecursos.vbom);
        long tiempos[] = new long[4];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 100;
        }
        //Se agrega a la escena
        nave.animate(tiempos, 0, tiempos.length - 1, true);
        //SpriteShooterMuriendo.setAnchorCenter(0.5f,0.0f);
        attachChild(nave);
    }

    private void agregarNaveChocando(){
        TiledTextureRegion regionNaveChocando = admRecursos.regionNaveChocando;
        naveChocando = new AnimatedSprite(150, 240,
                regionNaveChocando, admRecursos.vbom);
        long tiempos[] = new long[18];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 80;
        }
        //Se agrega a la escena
        naveChocando.animate(tiempos, 0, tiempos.length - 1, false);
        //SpriteShooterMuriendo.setAnchorCenter(0.5f,0.0f);
        attachChild(naveChocando);
    }


    private void agregarAsteroide(){
        asteroide = new Asteroide(ControlJuego.ANCHO_CAMARA,240,
                admRecursos.regionAsteroide,admRecursos.vbom);
        attachChild(asteroide.getSpriteAsteroide());
    }

    private void agregarAsteroideDos(){
        asteroideDos = new Asteroide(ControlJuego.ANCHO_CAMARA,120,
                admRecursos.regionAsteroide,admRecursos.vbom);
        attachChild(asteroideDos.getSpriteAsteroide());
    }

    private void agregarAsteroideTres(){
        asteroideTres = new Asteroide(ControlJuego.ANCHO_CAMARA,400,
                admRecursos.regionAsteroide,admRecursos.vbom);
        attachChild(asteroideTres.getSpriteAsteroide());
    }

    public void agregarMarcador() {
        marcador = new Marcador(admRecursos.engine, admRecursos.actividadJuego);
        admRecursos.camara.setHUD(marcador);
        marcador.quitarMarcadorMasAlto();
        marcador.quitarMarcadorMasAltoDos();
        marcador.quitarMarcador();
        marcador.quitarVidas();

        // Para marcador más alto. PRIMERO lee el marcador anterior
        SharedPreferences preferencias = admRecursos.actividadJuego.getSharedPreferences(
                "Estado", Context.MODE_PRIVATE);
        int vidas = preferencias.getInt("vidas",marcador.getVidas());
        marcador.setVidas(vidas);

        //para leer el putnaje actual
        int puntaje = preferencias.getInt("puntaje",marcador.getMarcador());
        marcador.setMarcador(puntaje);

        //puntaj mas alto
        int ultimoMarcador = preferencias.getInt("First",marcador.getMarcadorMasAlto());
        marcador.setMarcadorMasAlto(ultimoMarcador);

        //Segundo mas alto
        int penultimoMarcador = preferencias.getInt("Second",marcador.getMarcadorMasAlto());
        marcador.setMarcadorMasAltoDos(penultimoMarcador);


    }

    private void modificarVidas() {

        // guardarlo en las preferencias
        SharedPreferences preferencias = admRecursos.actividadJuego.getSharedPreferences(
                "Estado", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferencias.edit();
        editor.putInt("vidas", marcador.getVidas());
        editor.putInt("puntaje", marcador.getMarcador());
        editor.commit();

        int masAlto = marcador.getMarcadorMasAlto();
        int segundoMasAlto = marcador.getMarcadorMasAltoDos();
        int puntos = marcador.getMarcador();
        if (puntos>=masAlto) {
            editor.putInt("First",masAlto);
            editor.commit();
        }
        if(puntos>=segundoMasAlto && puntos<masAlto){
            editor.putInt("Second",segundoMasAlto);
            editor.commit();
        }

    }

    //Metodo del Timer
    private void agregarTimerAnimado() {
        TiledTextureRegion regionTimer = admRecursos.regionTimerTres;
        timer = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -45, regionTimer.getHeight()+345,
                regionTimer, admRecursos.vbom);
        // Arreglo de tiempos para los frames
        long tiempos[] = new long[11];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 1000;
        }
        //Se agrega a la escena
        timer.animate(tiempos,0,tiempos.length-1,false);
        attachChild(timer);
    }



    private void agregarMensajePerdiste() {
        // Creamos el sprite de manera optima
        mensajePerdiste = new Sprite(ControlJuego.ANCHO_CAMARA / 2, ControlJuego.ALTO_CAMARA / 2,
                admRecursos.regionPerdiste, admRecursos.vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }


        };

        attachChild(mensajePerdiste);

    }


    private void agregarMensajeGanaste() {
        // Creamos el sprite de manera �ptima
        mensajeGanaste = new Sprite(ControlJuego.ANCHO_CAMARA / 2, ControlJuego.ALTO_CAMARA / 2,
                admRecursos.regionGanaste, admRecursos.vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };
        attachChild(mensajeGanaste);

    }

    public boolean onSceneTouchEvent(TouchEvent pSceneTouchEvent) {
        float y = pSceneTouchEvent.getY();

        if (pSceneTouchEvent.isActionMove() && y < ControlJuego.ALTO_CAMARA/2){

            nave.setY(nave.getY()-10);

        }

        if(pSceneTouchEvent.isActionMove() && y > ControlJuego.ALTO_CAMARA/2){
            nave.setY(nave.getY()+10);

        }

        return super.onSceneTouchEvent(pSceneTouchEvent);
    }

    private void crearSonidos(){
        try {
            musicaFondo = MusicFactory.createMusicFromAsset(admRecursos.engine.getMusicManager(),
                    admRecursos.actividadJuego, "Niveles.mp3");
        }
        catch (IOException e) {
            Log.i("cargarSonidos", "No se puede cargar demo.ogg");
        }
        musicaFondo.setLooping(true);
        musicaFondo.play();
        try {
            efectoExplosion = SoundFactory.createSoundFromAsset(admRecursos.engine.getSoundManager(),
                    admRecursos.actividadJuego, "exploding.wav");
            efectoChoque = SoundFactory.createSoundFromAsset(admRecursos.engine.getSoundManager(),
                    admRecursos.actividadJuego, "explosion.wav");
        } catch (final IOException e) {
            Log.i("cargarSonidos","No se puede cargar efecto de sonido");
        }
        efectoExplosion.setVolume(0.5f);
        efectoChoque.setVolume(0.5f);
    }

    //Escena que ejecuta la pausa
    private void crearEscenaPausa(){
        escenaPausa = new MenuScene(admRecursos.camara);
        escenaPausa.setPosition(ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/2);

        //Fondo
        fondoPausa = new Sprite(ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/2,admRecursos.regionFondoPausaTres,admRecursos.vbom);
        SpriteBackground fondo = new SpriteBackground(0,0,0,fondoPausa);
        escenaPausa.setBackground(fondo);
        escenaPausa.setBackgroundEnabled(true);

        //Botones
        final IMenuItem opcionContinuar = new ScaleMenuItemDecorator(new SpriteMenuItem(OPCION_CONTINUAR,
                admRecursos.regionBotonContinuarTres,admRecursos.vbom), 1.5f, 1);
        final IMenuItem opcionMenu = new ScaleMenuItemDecorator(new SpriteMenuItem(OPCION_MENU,
                admRecursos.regionBotonMenuTres,admRecursos.vbom),1.5f,1);
        escenaPausa.addMenuItem(opcionContinuar);
        escenaPausa.addMenuItem(opcionMenu);
        escenaPausa.buildAnimations();
        opcionContinuar.setPosition(0,20);
        opcionMenu.setPosition(0,-70);

        escenaPausa.setOnMenuItemClickListener(new MenuScene.IOnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem, float pMenuItemLocalX, float pMenuItemLocalY) {
                switch (pMenuItem.getID()) {
                    case OPCION_CONTINUAR:
                        escenaPausa.back(false);
                        estaEnPausa = false;
                        EscenaJuegoTres.this.setIgnoreUpdate(false);
                        Log.i("Pausa", "Pausa");
                        break;
                    case OPCION_MENU:
                        regresarAMenu();
                        break;
                    default:
                        return false;
                }
                return true;
            }
        });
    }

    private void pausar(){
        setChildScene(escenaPausa, false, true, true);
    }

    private void agregarBtnPausa() {
        // Habilita los eventos de touch en ciertas areas
        setTouchAreaBindingOnActionDownEnabled(true);
        spriteBtnPausa = new ButtonSprite(150,450,admRecursos.regionBtnPausaTres, admRecursos.vbom) {
            @Override
            public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                if (pSceneTouchEvent.isActionUp()) {
                    estaEnPausa = true;
                }
                return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
            }
        };
        // Registra el area del boton
        registerTouchArea(spriteBtnPausa);
        attachChild(spriteBtnPausa);
    }

    // Regresar al menu principal
    private void regresarAMenu() {
        musicaFondo.stop();
        efectoChoque.stop();
        efectoExplosion.stop();
        admEscenas.crearEscenaMenu();
        admEscenas.setEscena(TipoEscena.ESCENA_MENU);
        admEscenas.liberarEscenaJuegoTres();
        admRecursos.camara.setHUD(null);


    }
    private void siguienteEscena(){
        musicaFondo.stop();
        efectoChoque.stop();
        efectoExplosion.stop();
        admEscenas.crearEscenaEstado();
        admEscenas.setEscena(TipoEscena.ESCENA_ESTADO);
        admEscenas.liberarEscenaJuegoTres();
        admRecursos.camara.setHUD(null);


    }

    // El usuario oprime el boton de BACK; regresar al menu principal
    @Override
    public void onBackKeyPressed() {
        if(estaEnPausa){
            escenaPausa.back();
            estaEnPausa = false;
            EscenaJuegoTres.this.setIgnoreUpdate(false);
        }
        //revisarMarcador();
        //regresarAMenu();
    }

    @Override
    public TipoEscena getTipoEscena() {
        return TipoEscena.ESCENA_JUEGOTRES;
    }

    @Override
    public void liberarEscena() {
        // Liberar cada recurso usado en esta escena
        spriteFondoJuegoTres.detachSelf();
        spriteFondoJuegoTres.dispose();
        musicaFondo.release();
        admRecursos.camara.setHUD(null);
        this.detachSelf();      // La escena misma se deconecta del engine
        this.dispose();         // Libera la memoria
    }

    public Music getMusicaFondo() {
        return musicaFondo;
    }

}
